package org.reborn.utils

import scala.math
import java.util.Date

object TimeUtil {

  def elapsedTime(block: => Unit):Double = {
    val start = System.nanoTime
    block
    val end = System.nanoTime
    (end - start) / 1000000.0
  }
  
  def elapsedTime[T](block: => T):(T,Double) = {
    val start = System.nanoTime
    val ret = block
    val end = System.nanoTime
    (ret, (end - start) / 1000000.0)
  }
  
  def performance(iterations:Int,warmupIterations:Int)(block:()=>Unit):(Double,Double,Double,Double,Double) = {
    var timeList:List[Double] = Nil
    for(i <- 0 until (iterations+warmupIterations)){
      val itrTime = elapsedTime{
        block():Unit
      }
      timeList = itrTime :: timeList 
    }
    
    timeList = timeList.drop(warmupIterations)
    timeList = timeList.sortWith(_ < _)
    val mean:Double = timeList.reduceLeft(_+_) / iterations.asInstanceOf[Double]
    val squaresList:List[Double] = timeList.map((a)=> math.pow((a - mean),2.0) )
    val stdDev = math.sqrt(squaresList.reduceLeft(_+_) / (iterations -1))
    val min = timeList.head
    val median = timeList(iterations / 2)
    val max = timeList.last
    (mean,stdDev,min,median,max)
  }
  
  def print(stats:(Double,Double,Double,Double,Double)):String = {
    "Mean:"+stats._1+"  Std. Dev.:"+stats._2+"  Min:"+stats._3+"  Median:"+stats._4+"  Max:"+stats._5 
  }
}
